﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using AgoritmoLibrary;

namespace EDA_TP_5847
{
    /// <summary>   1º formolario. </summary>
    ///
    /// <remarks>   Andre, 11/06/2013. </remarks>
    public partial class Form1 : Form
    {
        /// <summary>   Constructor. </summary>
        ///
        /// <remarks>   Andre Casaca, 11/06/2013. </remarks>
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>   Event handler. Chamado quando o button1 é clicado. </summary>
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Informacao do Evento. </param>
        private void button1_Click(object sender, EventArgs e)
        {
            this.progressBar1.Value = 0;
            Random rnd = new Random();
            List<Dictionary<int, double>> todosTempos = new List<Dictionary<int, double>>();
            Dictionary<int, double> temposExecucao = new Dictionary<int, double>();

            if (this.comboBox1.SelectedIndex != -1)
            {
                this.textBox1.Text = "";
                this.textBox1.Text += "--- " + this.comboBox1.SelectedItem.ToString() + " --- ";

                int incrementar = int.Parse(this.comboBox2.SelectedItem.ToString());
                int incrementarBarra = (int)this.numericUpDown2.Value / incrementar;
                for (int NExec = 0; NExec < this.numericUpDown5.Value; NExec++)
                {
                    temposExecucao = new Dictionary<int, double>();
                    for (int tamanhoLista = incrementar; tamanhoLista <= this.numericUpDown2.Value; tamanhoLista += incrementar)
                    {
                        List<int> lista = new List<int>();
                        for (int i = 0; i < tamanhoLista; i++)
                        {
                            int elemento = rnd.Next(0, (int)this.numericUpDown4.Value);
                            lista.Add(elemento);
                        }
                        Stopwatch time = new Stopwatch();
                        time.Start();
                        List<int> listaOrdenada = this.fazerAlgoritmoSeleccionado(this.comboBox1.SelectedItem.ToString(), lista);
                        time.Stop();
                        TimeSpan ts = time.Elapsed;
                        if (this.checkBox1.Checked)
                        {
                            this.textBox1.Text += Environment.NewLine;
                            foreach (int elemento in listaOrdenada)
                            {
                                this.textBox1.Text += elemento + ", ";
                            }
                            this.textBox1.Text += Environment.NewLine;
                        }
                        temposExecucao.Add(tamanhoLista, ts.TotalSeconds);
                        this.textBox1.Text += Environment.NewLine + tamanhoLista + " Elementos em: " + ts.TotalSeconds + " sec." ;
                        this.textBox1.Update();
                        this.progressBar1.Increment((100 / ((int)this.numericUpDown5.Value)) / incrementarBarra);
                    }
                    this.progressBar1.Increment(100 / ((int)this.numericUpDown5.Value));
                    todosTempos.Add(temposExecucao);
                }
                
                Form2 graficoDados = new Form2(todosTempos, this.comboBox1.SelectedItem.ToString());
                graficoDados.Show();
                this.progressBar1.Value = 100;
            }
            else
            {
                MessageBox.Show("Por favor Indique o Alguritmo a Testar");
            }
        }

        /// <summary>   Executa o algoritmo seleccionado. </summary>
        /// <param name="algoritmo">    O algoritmo. </param>
        /// <param name="lista">        A lista para ordenar. </param>
        ///
        /// <returns> A lista Já Ordenada </returns>
        private List<int> fazerAlgoritmoSeleccionado(string algoritmo, List<int> lista)
        {
            Sort sort = new Sort();
            switch (algoritmo)
            {
                case "InsertionSort":
                    return sort.InsertionSort(lista);
                case "BubbleSort":
                    return sort.BubbleSort(lista);
                case "HeapSort":
                    return sort.HeapSort(lista);
                case "MergeSort":
                    return sort.MergeSort(lista, 0, lista.Count-1);
                case "QuickSort":
                    return sort.QuickSort(lista, 0, lista.Count-1);
            }
            return null;
        }

        /// <summary>   Event handler. Chamado quando comboBox2 for clicado. </summary>
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        informacao do Event. </param>
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.label8.Text = "em " + this.comboBox2.SelectedItem.ToString();
            this.numericUpDown2.Increment = int.Parse(this.comboBox2.SelectedItem.ToString());
        }

        private void loseFocus(object sender, EventArgs e)
        {
            int resto = (int)this.numericUpDown2.Value % int.Parse(this.comboBox2.SelectedItem.ToString());
            if(resto != 0){
                this.numericUpDown2.Value -= resto;
            }
        }

        /// <summary>   Event handler. chamado quando o button2 for clicado. </summary>
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        informacao do Event. </param>
        private void button2_Click(object sender, EventArgs e)
        {
            this.button1.Enabled = false;
            this.button2.Enabled = false;

            this.comboBox1.SelectedIndex = -1;
            this.comboBox2.SelectedIndex = -1;
            this.numericUpDown2.Value = 0;
            this.numericUpDown5.Value = 0;
            this.numericUpDown4.Value = 0;

            this.textBox1.Clear();
        }

        /// <summary>   Quando a drop1 é modificada activa os botoes . </summary>
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        informacao do Event. </param>
        private void DropChanged(object sender, EventArgs e)
        {
            this.button1.Enabled = true;
            this.button2.Enabled = true;
        }
    }
}
